<?php
/**
 * @author 3Code Group 
 * @author Pawel Giemza
 * @version 1.0
 * @package Arrow
 * @subpackage Model
 * @link http://arrowplatform.org/
 * @copyright 2009 3code 
 * @license MIT
 * 
 * @date 2009-11-16 
*/
ArrowController::importModel("org.arrowplatform.model.IArrowControlable");
ArrowController::importModel("org.arrowplatform.model.ArrowModelIterator");
ArrowController::importModel("org.arrowplatform.model.IArrowModel");

class ArrowDatasetRow implements Iterator, ArrayAccess, IArrowControlable, IArrowModel{	
	private $data = array();
	private $mainClass = null; 
	private $current_obj = null;
	private $dataset = null;
	private $currentIteratorIndex = 0;
	private $mainObject;
	
	public function __construct($data, $dataset){
		$this->data = $data;
		$this->dataset = $dataset;
		$current_obj = null;
		$current_class = null;
		$keys = array_keys($this->data);
		$this->mainClass = $keys[0];
		$this->mainObject = $this->data[$keys[0]];
	}
	
	public function getObject($class = ""){
		if($class=="")
			return $this->data[$this->mainClass];
		return $this->data[$class];
	}
	
	public function getPKey(){
		return $this->data[$this->mainClass]->getPKey();
	}
	public static function getActions( $model, $type = null ){
		return call_user_func(array($this->mainClass , "getActions"), $model, $type );
	}
	public function getInstanceActions(){
		return $this->data[$this->mainClass]->getInstanceActions();
	}
	
	public function getClass(){
		return $this->mainClass;
	}
	
	public function getModel(){
		return $this->data[$this->mainClass]->getModel();
	}
	
	public function getRel($rel){
		return $this->data[$this->mainClass]->getRel($rel);
	}
	
	public function setValue($field, $value, $tmp = false){
		$result = $this->data[$this->mainClass]->setValue($field, $value, $tmp);
		
		if(!isset($this->dataset->namesDictionary[$field]))
			$this->dataset->namesDictionary[$field] = array( $this->mainClass, $field );
		
		return $result;
	}
	
	
	
	public function rewind() {
		$this->currentIteratorIndex = 0;
		$obj = reset($this->data);
		if (is_object($obj)){
			$this->current_obj = $obj->getIterator();
			$this->current_obj->rewind();
			$this->current_class = $this->current_obj->objClass();
		}
		else{ //array
			throw new ArrowException('Main class has to be real object not array');
		}
	}

	public function current() {
		if (is_object($this->current_obj))	
			$var =  $this->current_obj->current();
		else
			$var =  current($this->current_obj);
		return $var;
	}

	public function key() {
		if (is_object($this->current_obj))	
			$key = $this->current_obj->key();
		else
			$key = key($this->current_obj);
		return $this->current_class.':'.$key;
	}

	public function next() {
		$var = false;
		if ($this->current_obj){
			$this->currentIteratorIndex++;
			if (is_object($this->current_obj))	
				$var = $this->current_obj->next();
			else
				$var =	next($this->current_obj);
				
			if ($var === false && current($this->data)){
				$add = next($this->data);
				$addClass = key($this->data);
				if ($add && is_object($add))
					$add = $add->getIterator();
					
				$this->current_obj = $add;
				if ($this->current_obj){
					if (is_object($this->current_obj)){
						$var = $this->current_obj->rewind();
						$this->current_class = $addClass;
					}else{
						$var = reset($this->current_obj);
						$this->current_class = $addClass;
					}
				}
			}
		}
		return $var;
	}
	
	public function valid() {
		if( $this->current_obj && ( (is_object($this->current_obj) && $this->current_obj->current() !== false) || (is_array($this->current_obj) && current($this->current_obj) !== false) ) )
			return true;
		return false ;  		
	}
	
	public function offsetExists($offset){
		return isset($this->dataset->namesDictionary[$offset]);
	}
	
	public function offsetSet($offset,$value){
		throw new ArrowException('Its not possible to set field values while using ArrowDataset');
	}
	
	
	public function getValue($field){
		
		if(array_key_exists($field, $this->dataset->namesDictionary)){
			$pointer = $this->dataset->namesDictionary[$field];
			try {
				if(is_object($this->data[$pointer[0]])){					
					return $this->data[$pointer[0]]->getValue($pointer[1]);
				}else{
					return $this->data[$pointer[0]][$pointer[1]];
				}
			} catch( Exception $e ) {
				throw new ArrowException("Niespójne dane wierszy, Każdy wiersz musi zawierać pole `$field`");
			}
		}else{
			throw new ArrowOrmException(array(
				"msg" => "Can't find index in row names dictionary",
				"toFind" => $field,
				"dictionary" => $this->dataset->namesDictionary
			));
		}
	}
	
	public function offsetGet($offset){
		return $this->getValue($offset);
	}
	
	public function offsetUnset($offset){
		throw new ArrowException('Its not possible to unset field while using ArrowDataset');
	}
	
	/**
	* print - print directly to screen or return 
	* $independent - return only datarow or also the headers
	*/
	public function dump($print=true,$independent=true){
    $data = array();
    foreach ($this->dataset->namesDictionary as $field=>$pointer){
      if(is_object($this->data[$pointer[0]])){
        $data[$field] = $this->data[$pointer[0]]->getValue($pointer[1]);
      }else{
        $data[$field] = $this->data[$pointer[0]][$pointer[1]];
      }
      if (empty($data[$field]))
        $data[$field] = '&nbsp;';
    }
    $ret = '';
    if ($independent){
      //prepare headers
      $ret = '<table border="1"><tr><th>'.implode('</th><th>',array_keys($data)).'</th></tr>';
    }
    //prepare data
      $ret .= '<tr>';
      foreach($data as $key=>$val){
        $ret .= '<td>'.print_r($data,true).'</td>';
      }  
      $ret .= '</tr>';
    if ($independent){
      $ret.='</table>';
    }
    if ($print)
      print_r($ret);
    else
      return $ret;
	}
}
?>